﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Windows.Forms;

namespace CIRDiagnoseDevice.Test
{
    class SendTaxData
    {
        #region 变量
        public static int TrainNum; //车次号保存
        public static string TrainType;//车次种类
        public static string CabNO;//机车号保存
        public static string CabType; // 机车型号保存
        private bool HaveSetTrainNum;// 判断是否设置机车号与车次号
        TaxDataTrainNumAndCabNo taxForm;
        #endregion

        private byte[] GetDigFrameData(byte status, ushort speed)
        {
            try
            {
                if (!HaveSetTrainNum)
                {
                    taxForm = new TaxDataTrainNumAndCabNo();
                    taxForm.ShowDialog();
                    HaveSetTrainNum = true;
                }
                byte[] temp = new byte[82];
                temp[0] = 0x00;//信息长度2字节
                temp[1] = 0x50;
                temp[2] = 0x11;//源端口代码
                temp[3] = 0x00;//源地址长度
                temp[4] = 0x01;//目的端口代码
                temp[5] = 0x00;  // 目的地址长度
                temp[6] = 0x05;      //业务类型  
                temp[7] = 0x21;       //命令
                temp[8] = 0x38;     //本板地址
                temp[9] = 0x00;      //特征码
                temp[10] = 0x67;    //标志
                temp[11] = 0x01;   // 版本号
                temp[12] = 0x00;  // 保留字节
                temp[13] = 0x00;    //车站号
                if (TaxDataTrainNumAndCabNo.TrainType != "")
                {
                    string stri = TaxDataTrainNumAndCabNo.TrainType;
                    TrainType = stri;
                    byte[] trainTypeFlag = System.Text.ASCIIEncoding.Default.GetBytes(stri);
                    for (int i = 0; i < 4; i++)
                    {
                        if (i < 4 - stri.Length)
                        {
                            temp[14 + i] = 0x20; //车次种类标识符4字节
                        }
                        else
                        {
                            temp[14 + i] = trainTypeFlag[i + stri.Length - 4];
                        }
                    }
                }
                else
                {
                    temp[14] = 0x20;    //车次种类标识符4字节
                    temp[15] = 0x20;
                    temp[16] = 0x20;
                    temp[17] = 0x20;
                    TrainType = "";
                }
                temp[18] = 0x00;    //司机号扩充字节
                temp[19] = 0x00;    //副司机号扩充字节
                temp[20] = 0x00;    //保留2 字节
                temp[21] = 0x00;
                temp[22] = 0x00;     // 机车型号扩充字节
                temp[23] = 0x01;      //实际交路号
                for (int i = 0; i < 11; i++)
                {
                    temp[24 + i] = 0x00;          // 保留11字节
                }
                temp[35] = 0x01;  // 本/补、客/货
                int trainNum;
                int.TryParse(TaxDataTrainNumAndCabNo.TrainNum, out trainNum);
                TrainNum = trainNum;
                temp[36] = (byte)trainNum; //车次数字部分3字节
                temp[37] = (byte)(trainNum >> 8);
                temp[38] = (byte)(trainNum >> 16);
                byte check1 = 0;
                for (int i = 8; i < 39; i++)
                {
                    check1 += temp[i];
                }
                check1 = (byte)((check1 ^ 0xff) + 1);
                temp[39] = check1;  // 检查和1
                temp[40] = 0x39;     //本板地址
                temp[41] = 0x30;      //特征码，30表示上次接收成功，c0表示上次接收失败
                temp[42] = 0x04;     // 检测单元代号
                DateTime time = System.DateTime.Now;
                uint intTime = toint(time);
                temp[43] = (byte)intTime; //时间4字节从年到秒
                temp[44] = (byte)(intTime >> 8);
                temp[45] = (byte)(intTime >> 16);
                temp[46] = (byte)(intTime >> 24);
                temp[47] = (byte)speed;  // 列车实速3字节
                temp[48] = (byte)(speed >> 8);
                temp[49] = 0x00;
                temp[50] = 0x01;    //机车信号
                temp[51] = 0x01;    //机车式况
                ushort signallor = 3;
                temp[52] = (byte)signallor;         //信号机编号2字节
                temp[53] = (byte)(signallor >> 8);
                temp[54] = 0x02;  // 33 信号机种类
                uint kilometer_post = 1200;
                temp[55] = (byte)kilometer_post; // 34 公里标3字节
                temp[56] = (byte)(kilometer_post >> 8);
                temp[57] = (byte)(kilometer_post >> 16);
                ushort trainHeight = 550;                      //车重
                temp[58] = (byte)trainHeight;
                temp[59] = (byte)(trainHeight >> 8);
                ushort trainLength = 200;  // 车长
                temp[60] = (byte)trainLength;
                temp[61] = (byte)(trainLength >> 8);
                byte railwayNum = 0x32; //编组辆数
                temp[62] = railwayNum;
                temp[63] = 0x01;
                temp[64] = (byte)(trainNum >> 8);
                temp[65] = (byte)trainNum;
                byte sectionNum = 0x01; //区段号
                temp[66] = sectionNum;
                byte stationNum = 0x01; // 车站号
                temp[67] = stationNum;
                ushort driverNum = 1; // 司机号
                temp[68] = (byte)driverNum;
                temp[69] = (byte)(driverNum >> 8);
                ushort viDrivNum = 2; // 副司机号
                temp[70] = (byte)viDrivNum;
                temp[71] = (byte)(viDrivNum >> 8);
                ushort trainNO;
                ushort.TryParse(TaxDataTrainNumAndCabNo.CabNo, out trainNO); // 机车号
                temp[72] = (byte)trainNO;
                temp[73] = (byte)(trainNO >> 8);
                byte trainType;
                byte.TryParse(TaxDataTrainNumAndCabNo.CabType, out trainType);//机车型号
                CabNO = TaxDataTrainNumAndCabNo.CabType + TaxDataTrainNumAndCabNo.CabNo;
                temp[74] = trainType;
                temp[75] = 0x58;
                temp[76] = 0x02;
                temp[77] = status;
                temp[78] = 0x00;
                byte check2 = 0x00;
                for (int j = 40; j < 79; j++)
                {
                    check2 += temp[j];
                }
                temp[79] = (byte)((check2 ^ 0xff) + 1);  //二进制补码
                ushort checkSum = crc_16.CalculateCRC(temp, 0, (ushort)80);
                temp[80] = (byte)(checkSum >> 8);
                temp[81] = (byte)checkSum;
                return temp;
            }
            catch(Exception e)
            {
                MessageBox.Show(e.Message);
                return null;
            }
        }

        //打包数据
        private byte[] PacketData(byte[] data)
        {
            ArrayList packetedData = new ArrayList();

            for (int i = 0; i < data.Length; i++)
            {
                packetedData.Add(data[i]);
                if (data[i] == 0x10)
                {
                    packetedData.Add(data[i]);
                }

            }
            return (byte[])(packetedData.ToArray(typeof(byte)));
        }

        // 将日期转换成四字节
        public static uint toint(DateTime dt)
        {
            uint x = 0;
            x += (uint)(dt.Year - 2000) << 26;
            x += (uint)dt.Month << 22;
            x += (uint)dt.Day << 17;
            x += (uint)dt.Hour << 12;
            x += (uint)dt.Minute << 6;
            x += (uint)dt.Second;
            return x;
        }

        public byte[] SendDigData(byte status,ushort speed)
        {
            ArrayList sendData = new ArrayList();
            sendData.Add((byte)0x10);
            sendData.Add((byte)0x02);
            byte[] frameData = GetDigFrameData(status, speed);
            if (frameData != null)
            {
                byte[] packetData = PacketData(frameData);
                for (int i = 0; i < packetData.Length; i++)
                {
                    sendData.Add(packetData[i]);
                }
            }
            sendData.Add((byte)0x10);
            sendData.Add((byte)0x03);
            byte[] sendArray = new byte[sendData.Count];
            sendData.CopyTo(sendArray);
            return sendArray;
        }
    }
}
